{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "f28455fa",
   "metadata": {},
   "outputs": [],
   "source": [
    "import pandas as pd\n",
    "import numpy as np\n",
    "\n",
    "# data visualization\n",
    "import matplotlib.pyplot as plt\n",
    "import seaborn as sns\n",
    "%matplotlib inline\n",
    "\n",
    "import tensorflow as tf\n",
    "from sklearn.preprocessing import MinMaxScaler\n",
    "from keras.models import Sequential\n",
    "from keras.layers import LSTM,Dense,Dropout\n",
    "from sklearn.metrics import mean_squared_error,mean_absolute_error,r2_score\n",
    "\n",
    "import math \n",
    "import os "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "506cd016",
   "metadata": {},
   "outputs": [],
   "source": [
    "plt.rcParams['font.sans-serif']=['SimHei'] #用来正常显示中文标签\n",
    "plt.rcParams['axes.unicode_minus']=False #用来正常显示负号\n",
    "sns.set(font='SimHei')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "2fd9ce76",
   "metadata": {},
   "outputs": [],
   "source": [
    "df= pd.read_csv('../dataset/min.csv')  # 读取股票文件"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "61c70e7a",
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>时间</th>\n",
       "      <th>开盘</th>\n",
       "      <th>收盘</th>\n",
       "      <th>最高</th>\n",
       "      <th>最低</th>\n",
       "      <th>成交量</th>\n",
       "      <th>成交额</th>\n",
       "      <th>最新价</th>\n",
       "      <th>code</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>2021-11-19 09:30:00</td>\n",
       "      <td>17.80</td>\n",
       "      <td>17.80</td>\n",
       "      <td>17.80</td>\n",
       "      <td>17.80</td>\n",
       "      <td>4127</td>\n",
       "      <td>7346060</td>\n",
       "      <td>17.80</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>2021-11-19 09:30:00</td>\n",
       "      <td>19.01</td>\n",
       "      <td>19.01</td>\n",
       "      <td>19.01</td>\n",
       "      <td>19.01</td>\n",
       "      <td>1718</td>\n",
       "      <td>3265918</td>\n",
       "      <td>19.01</td>\n",
       "      <td>2</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>2021-11-19 09:30:00</td>\n",
       "      <td>18.84</td>\n",
       "      <td>18.84</td>\n",
       "      <td>18.84</td>\n",
       "      <td>18.84</td>\n",
       "      <td>568</td>\n",
       "      <td>1070112</td>\n",
       "      <td>18.84</td>\n",
       "      <td>4</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>2021-11-19 09:30:00</td>\n",
       "      <td>4.12</td>\n",
       "      <td>4.12</td>\n",
       "      <td>4.12</td>\n",
       "      <td>4.12</td>\n",
       "      <td>29</td>\n",
       "      <td>11750</td>\n",
       "      <td>4.12</td>\n",
       "      <td>6</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>2021-11-19 09:30:00</td>\n",
       "      <td>2.14</td>\n",
       "      <td>2.14</td>\n",
       "      <td>2.14</td>\n",
       "      <td>2.14</td>\n",
       "      <td>165</td>\n",
       "      <td>35310</td>\n",
       "      <td>2.14</td>\n",
       "      <td>8</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "                    时间     开盘     收盘     最高     最低   成交量      成交额    最新价  code\n",
       "0  2021-11-19 09:30:00  17.80  17.80  17.80  17.80  4127  7346060  17.80     1\n",
       "1  2021-11-19 09:30:00  19.01  19.01  19.01  19.01  1718  3265918  19.01     2\n",
       "2  2021-11-19 09:30:00  18.84  18.84  18.84  18.84   568  1070112  18.84     4\n",
       "3  2021-11-19 09:30:00   4.12   4.12   4.12   4.12    29    11750   4.12     6\n",
       "4  2021-11-19 09:30:00   2.14   2.14   2.14   2.14   165    35310   2.14     8"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df.head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "6f053bd1",
   "metadata": {},
   "outputs": [],
   "source": [
    "df = df.loc[df['code'] == 600000]\n",
    "df.drop(['code'],axis=1,inplace=True)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "27096402",
   "metadata": {},
   "outputs": [],
   "source": [
    "df.set_index('时间',inplace=True)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "c757db94",
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>开盘</th>\n",
       "      <th>收盘</th>\n",
       "      <th>最高</th>\n",
       "      <th>最低</th>\n",
       "      <th>成交量</th>\n",
       "      <th>成交额</th>\n",
       "      <th>最新价</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>时间</th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>2021-11-19 09:30:00</th>\n",
       "      <td>8.56</td>\n",
       "      <td>8.56</td>\n",
       "      <td>8.56</td>\n",
       "      <td>8.56</td>\n",
       "      <td>751</td>\n",
       "      <td>642856</td>\n",
       "      <td>8.560</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2021-11-19 09:31:00</th>\n",
       "      <td>8.55</td>\n",
       "      <td>8.56</td>\n",
       "      <td>8.58</td>\n",
       "      <td>8.55</td>\n",
       "      <td>2536</td>\n",
       "      <td>2171176</td>\n",
       "      <td>8.562</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2021-11-19 09:32:00</th>\n",
       "      <td>8.58</td>\n",
       "      <td>8.58</td>\n",
       "      <td>8.58</td>\n",
       "      <td>8.55</td>\n",
       "      <td>1127</td>\n",
       "      <td>965498</td>\n",
       "      <td>8.563</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2021-11-19 09:33:00</th>\n",
       "      <td>8.58</td>\n",
       "      <td>8.57</td>\n",
       "      <td>8.58</td>\n",
       "      <td>8.56</td>\n",
       "      <td>433</td>\n",
       "      <td>371053</td>\n",
       "      <td>8.563</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2021-11-19 09:34:00</th>\n",
       "      <td>8.57</td>\n",
       "      <td>8.58</td>\n",
       "      <td>8.58</td>\n",
       "      <td>8.57</td>\n",
       "      <td>1207</td>\n",
       "      <td>1034632</td>\n",
       "      <td>8.565</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "                       开盘    收盘    最高    最低   成交量      成交额    最新价\n",
       "时间                                                               \n",
       "2021-11-19 09:30:00  8.56  8.56  8.56  8.56   751   642856  8.560\n",
       "2021-11-19 09:31:00  8.55  8.56  8.58  8.55  2536  2171176  8.562\n",
       "2021-11-19 09:32:00  8.58  8.58  8.58  8.55  1127   965498  8.563\n",
       "2021-11-19 09:33:00  8.58  8.57  8.58  8.56   433   371053  8.563\n",
       "2021-11-19 09:34:00  8.57  8.58  8.58  8.57  1207  1034632  8.565"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df.head()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "160539e0",
   "metadata": {},
   "source": [
    "## 数据检查"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "54a2df6e",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Function to check the missing percent of a DatFrame;\n",
    "def check_missing_data(df):\n",
    "    total = df.isnull().sum().sort_values(ascending = False)\n",
    "    percent = round(df.isnull().sum().sort_values(ascending = False) * 100 /len(df),2)\n",
    "    return pd.concat([total, percent], axis=1, keys=['Total','Percent'])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "862a721d",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>Total</th>\n",
       "      <th>Percent</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>开盘</th>\n",
       "      <td>0</td>\n",
       "      <td>0.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>收盘</th>\n",
       "      <td>0</td>\n",
       "      <td>0.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>最高</th>\n",
       "      <td>0</td>\n",
       "      <td>0.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>最低</th>\n",
       "      <td>0</td>\n",
       "      <td>0.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>成交量</th>\n",
       "      <td>0</td>\n",
       "      <td>0.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>成交额</th>\n",
       "      <td>0</td>\n",
       "      <td>0.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>最新价</th>\n",
       "      <td>0</td>\n",
       "      <td>0.0</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "     Total  Percent\n",
       "开盘       0      0.0\n",
       "收盘       0      0.0\n",
       "最高       0      0.0\n",
       "最低       0      0.0\n",
       "成交量      0      0.0\n",
       "成交额      0      0.0\n",
       "最新价      0      0.0"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "check_missing_data(df)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "350f50c5",
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 2 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "sns.heatmap(df.corr())\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "id": "c94543c3",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[0.06666946 0.06666946 0.         ... 0.06737782 0.06687932 0.        ]\n",
      " [0.         0.06666946 0.1428566  ... 0.230124   0.22846356 0.03077698]\n",
      " [0.20000076 0.20000076 0.1428566  ... 0.10165937 0.1009912  0.04614258]\n",
      " ...\n",
      " [0.7333336  0.66666794 0.7142868  ... 0.03501094 0.03515772 0.98461914]\n",
      " [0.66666794 0.66666794 0.7142868  ... 0.29385483 0.29475513 0.98461914]\n",
      " [0.66666794 0.66666794 0.6428566  ... 0.15007295 0.15049942 1.        ]]\n"
     ]
    }
   ],
   "source": [
    "#获取DataFrame中的数据，形式为数组array形式\n",
    "values=df.values\n",
    "#确保所有数据为float类型\n",
    "values=values.astype('float32')\n",
    " \n",
    "# 特征的归一化处理\n",
    "scaler = MinMaxScaler(feature_range=(0, 1))\n",
    "scaled = scaler.fit_transform(values)\n",
    "print(scaled)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "id": "bee1cd05",
   "metadata": {},
   "outputs": [],
   "source": [
    "# 定义series_to_supervised()函数\n",
    "# 将时间序列转换为监督学习问题\n",
    "def series_to_supervised(data, n_in=1, n_out=1, dropnan=True):\n",
    "    \"\"\"\n",
    "    将时间序列框定为有监督的学习数据集。\n",
    "        论据：\n",
    "        数据：作为列表或NumPy数组的观察序列。\n",
    "        n_in：作为输入的滞后观测数（X）。\n",
    "        n_out：作为输出的观察数（y）。\n",
    "        dropnan：布尔值，决定是否删除具有NaN值的行。\n",
    "    返回：\n",
    "    pd.DataFrame(用于监督学习)\n",
    "    \"\"\"\n",
    "    n_vars = 1 if type(data) is list else data.shape[1]\n",
    "    df = pd.DataFrame(data)\n",
    "    cols, names = list(), list()\n",
    "    # input sequence (t-n, ... t-1)\n",
    "    for i in range(n_in, 0, -1):\n",
    "        cols.append(df.shift(i))\n",
    "        names += [('var%d(t-%d)' % (j + 1, i)) for j in range(n_vars)]\n",
    "    # forecast sequence (t, t+1, ... t+n)\n",
    "    for i in range(0, n_out):\n",
    "        cols.append(df.shift(-i))\n",
    "        if i == 0:\n",
    "            names += [('var%d(t)' % (j + 1)) for j in range(n_vars)]\n",
    "        else:\n",
    "            names += [('var%d(t+%d)' % (j + 1, i)) for j in range(n_vars)]\n",
    "    # put it all together\n",
    "    agg = pd.concat(cols, axis=1)\n",
    "    agg.columns = names\n",
    "    # drop rows with NaN values\n",
    "    if dropnan:\n",
    "        agg.dropna(inplace=True)\n",
    "    return agg"
   ]
  },
  {
   "cell_type": "raw",
   "id": "f331b2f2",
   "metadata": {},
   "source": [
    "该函数有四个参数：\n",
    "\n",
    "    data：输入数据需要是列表或二维的NumPy数组的观察序列。\n",
    "    n_in：输入的滞后观察数（X）。值可以在[1..len（data）]之间，可选的。默认为1。\n",
    "    n_out：输出的观察数（y）。值可以在[0..len（data）-1]之间，可选的。默认为1。\n",
    "    dropnan：Bool值，是否删除具有NaN值的行，可选的。默认为True。\n",
    "\n",
    "该函数返回一个值：\n",
    "\n",
    "    返回：用于监督学习的Pandas DataFrame。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "id": "6ef2ef1e",
   "metadata": {
    "scrolled": true
   },
   "outputs": [],
   "source": [
    "#将时间序列转换为监督学习问题\n",
    "reframed = series_to_supervised(scaled, 1, 1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "id": "76bad08c",
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>var1(t-1)</th>\n",
       "      <th>var2(t-1)</th>\n",
       "      <th>var3(t-1)</th>\n",
       "      <th>var4(t-1)</th>\n",
       "      <th>var5(t-1)</th>\n",
       "      <th>var6(t-1)</th>\n",
       "      <th>var7(t-1)</th>\n",
       "      <th>var1(t)</th>\n",
       "      <th>var2(t)</th>\n",
       "      <th>var3(t)</th>\n",
       "      <th>var4(t)</th>\n",
       "      <th>var5(t)</th>\n",
       "      <th>var6(t)</th>\n",
       "      <th>var7(t)</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>0.066669</td>\n",
       "      <td>0.066669</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.071430</td>\n",
       "      <td>0.067378</td>\n",
       "      <td>0.066879</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.066669</td>\n",
       "      <td>0.142857</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.230124</td>\n",
       "      <td>0.228464</td>\n",
       "      <td>0.030777</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.066669</td>\n",
       "      <td>0.142857</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.230124</td>\n",
       "      <td>0.228464</td>\n",
       "      <td>0.030777</td>\n",
       "      <td>0.200001</td>\n",
       "      <td>0.200001</td>\n",
       "      <td>0.142857</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.101659</td>\n",
       "      <td>0.100991</td>\n",
       "      <td>0.046143</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>0.200001</td>\n",
       "      <td>0.200001</td>\n",
       "      <td>0.142857</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.101659</td>\n",
       "      <td>0.100991</td>\n",
       "      <td>0.046143</td>\n",
       "      <td>0.200001</td>\n",
       "      <td>0.133331</td>\n",
       "      <td>0.142857</td>\n",
       "      <td>0.071430</td>\n",
       "      <td>0.038384</td>\n",
       "      <td>0.038142</td>\n",
       "      <td>0.046143</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>0.200001</td>\n",
       "      <td>0.133331</td>\n",
       "      <td>0.142857</td>\n",
       "      <td>0.071430</td>\n",
       "      <td>0.038384</td>\n",
       "      <td>0.038142</td>\n",
       "      <td>0.046143</td>\n",
       "      <td>0.133331</td>\n",
       "      <td>0.200001</td>\n",
       "      <td>0.142857</td>\n",
       "      <td>0.142857</td>\n",
       "      <td>0.108953</td>\n",
       "      <td>0.108301</td>\n",
       "      <td>0.076920</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5</th>\n",
       "      <td>0.133331</td>\n",
       "      <td>0.200001</td>\n",
       "      <td>0.142857</td>\n",
       "      <td>0.142857</td>\n",
       "      <td>0.108953</td>\n",
       "      <td>0.108301</td>\n",
       "      <td>0.076920</td>\n",
       "      <td>0.200001</td>\n",
       "      <td>0.200001</td>\n",
       "      <td>0.214287</td>\n",
       "      <td>0.142857</td>\n",
       "      <td>0.146335</td>\n",
       "      <td>0.145592</td>\n",
       "      <td>0.123077</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "   var1(t-1)  var2(t-1)  var3(t-1)  var4(t-1)  var5(t-1)  var6(t-1)  \\\n",
       "1   0.066669   0.066669   0.000000   0.071430   0.067378   0.066879   \n",
       "2   0.000000   0.066669   0.142857   0.000000   0.230124   0.228464   \n",
       "3   0.200001   0.200001   0.142857   0.000000   0.101659   0.100991   \n",
       "4   0.200001   0.133331   0.142857   0.071430   0.038384   0.038142   \n",
       "5   0.133331   0.200001   0.142857   0.142857   0.108953   0.108301   \n",
       "\n",
       "   var7(t-1)   var1(t)   var2(t)   var3(t)   var4(t)   var5(t)   var6(t)  \\\n",
       "1   0.000000  0.000000  0.066669  0.142857  0.000000  0.230124  0.228464   \n",
       "2   0.030777  0.200001  0.200001  0.142857  0.000000  0.101659  0.100991   \n",
       "3   0.046143  0.200001  0.133331  0.142857  0.071430  0.038384  0.038142   \n",
       "4   0.046143  0.133331  0.200001  0.142857  0.142857  0.108953  0.108301   \n",
       "5   0.076920  0.200001  0.200001  0.214287  0.142857  0.146335  0.145592   \n",
       "\n",
       "    var7(t)  \n",
       "1  0.030777  \n",
       "2  0.046143  \n",
       "3  0.046143  \n",
       "4  0.076920  \n",
       "5  0.123077  "
      ]
     },
     "execution_count": 14,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "reframed.head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "id": "aaaf7b39",
   "metadata": {
    "scrolled": false
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>var1(t-1)</th>\n",
       "      <th>var2(t-1)</th>\n",
       "      <th>var3(t-1)</th>\n",
       "      <th>var4(t-1)</th>\n",
       "      <th>var5(t-1)</th>\n",
       "      <th>var6(t-1)</th>\n",
       "      <th>var7(t-1)</th>\n",
       "      <th>var7(t)</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>0.066669</td>\n",
       "      <td>0.066669</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.071430</td>\n",
       "      <td>0.067378</td>\n",
       "      <td>0.066879</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.030777</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.066669</td>\n",
       "      <td>0.142857</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.230124</td>\n",
       "      <td>0.228464</td>\n",
       "      <td>0.030777</td>\n",
       "      <td>0.046143</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>0.200001</td>\n",
       "      <td>0.200001</td>\n",
       "      <td>0.142857</td>\n",
       "      <td>0.000000</td>\n",
       "      <td>0.101659</td>\n",
       "      <td>0.100991</td>\n",
       "      <td>0.046143</td>\n",
       "      <td>0.046143</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>0.200001</td>\n",
       "      <td>0.133331</td>\n",
       "      <td>0.142857</td>\n",
       "      <td>0.071430</td>\n",
       "      <td>0.038384</td>\n",
       "      <td>0.038142</td>\n",
       "      <td>0.046143</td>\n",
       "      <td>0.076920</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5</th>\n",
       "      <td>0.133331</td>\n",
       "      <td>0.200001</td>\n",
       "      <td>0.142857</td>\n",
       "      <td>0.142857</td>\n",
       "      <td>0.108953</td>\n",
       "      <td>0.108301</td>\n",
       "      <td>0.076920</td>\n",
       "      <td>0.123077</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "   var1(t-1)  var2(t-1)  var3(t-1)  var4(t-1)  var5(t-1)  var6(t-1)  \\\n",
       "1   0.066669   0.066669   0.000000   0.071430   0.067378   0.066879   \n",
       "2   0.000000   0.066669   0.142857   0.000000   0.230124   0.228464   \n",
       "3   0.200001   0.200001   0.142857   0.000000   0.101659   0.100991   \n",
       "4   0.200001   0.133331   0.142857   0.071430   0.038384   0.038142   \n",
       "5   0.133331   0.200001   0.142857   0.142857   0.108953   0.108301   \n",
       "\n",
       "   var7(t-1)   var7(t)  \n",
       "1   0.000000  0.030777  \n",
       "2   0.030777  0.046143  \n",
       "3   0.046143  0.046143  \n",
       "4   0.046143  0.076920  \n",
       "5   0.076920  0.123077  "
      ]
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 删除不想预测的特征列，这里只预测收盘价\n",
    "# 所以删除的是var1(t),var2(t),var3(t),\n",
    "reframed.drop(['var1(t)','var2(t)','var3(t)','var4(t)','var5(t)','var6(t)'], axis=1, inplace=True)\n",
    "# 打印数据的前5行\n",
    "reframed.head()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c52b915c",
   "metadata": {},
   "source": [
    "## 数据划分为训练集和测试集：\n",
    "\n",
    "* 将处理后的数据集划分为训练集和测试集。这里按0.85比例划分，将训练集和测试集的最终输入（X）转换为为LSTM的输入格式，即[samples,timesteps,features]。\n",
    "\n",
    "* Keras LSTM层的工作方式是通过接收3维（N，W，F）的数字阵列，其中N是训练序列的数目，W是序列长度，F是每个序列的特征数目。\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "id": "1fb4061b",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(201, 1, 7) (201,)\n",
      "(36, 1, 7) (36,)\n"
     ]
    }
   ],
   "source": [
    "# 划分训练集和测试集\n",
    "train = reframed.iloc[:int(len(reframed)*0.85),:].values\n",
    "test = reframed.iloc[int(len(reframed)*0.85):,:].values\n",
    "# 划分训练集和测试集的输入和输出\n",
    "train_X, train_y = train[:, :-1], train[:, -1]\n",
    "test_X, test_y = test[:, :-1], test[:, -1]\n",
    "#转化为三维数据\n",
    "# reshape input to be 3D [samples, timesteps, features]\n",
    "train_X = train_X.reshape((train_X.shape[0], 1, train_X.shape[1]))\n",
    "test_X = test_X.reshape((test_X.shape[0], 1, test_X.shape[1]))\n",
    "print(train_X.shape, train_y.shape)\n",
    "print(test_X.shape, test_y.shape)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "7f65a19c",
   "metadata": {},
   "source": [
    "# 模型构建及其预测"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "012a2906",
   "metadata": {},
   "source": [
    "* 搭建LSTM模型并绘制损失图\n",
    "    * 本实验使用keras深度学习框架对模型进行快速搭建。建立Sequential模型，向其中添加LSTM层，设定Dropout为0.5，加入Dense层将其维度聚合为1，激活函数使用relu（也用了sigmoid作为激活函数，但实验效果不如relu），损失函数定为均方差Mean Absolute Error(MAE)。优化算法采用Adam，模型采用50个epochs并且每个batch的大小为100。其中：隐藏层有64个神经元，输出层1个神经元（回归问题），输入变量是一个时间步（t-1）的特征。在fit()函数中设置validation_data参数，记录训练集和测试集的损失。"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e3ee2975",
   "metadata": {},
   "source": [
    "### 预测一次，并保存预测结构，用于之后的验证"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "id": "b71edde8",
   "metadata": {},
   "outputs": [],
   "source": [
    "checkpoint_save_path = \"./checkpoint/test_4_1.ckpt\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "id": "e85a0f7c",
   "metadata": {
    "scrolled": true
   },
   "outputs": [],
   "source": [
    "cp_callback = tf.keras.callbacks.ModelCheckpoint(filepath=checkpoint_save_path,\n",
    "                                                 save_weights_only=True,\n",
    "                                                 save_best_only=True,\n",
    "                                                 monitor='val_loss')"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a38a1a38",
   "metadata": {},
   "source": [
    "* LSTM(neurons, input_shape=(input_timesteps, input_dim), return_sequences=return_seq)\n",
    "* Dropout(dropout_rate)\n",
    "* Dense(neurons, activation=activation)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "id": "e41c3d1a",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(1, 7)"
      ]
     },
     "execution_count": 19,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "train_X.shape[1], train_X.shape[2]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "id": "2738cd6d",
   "metadata": {
    "scrolled": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch 1/50\n",
      "3/3 - 9s - loss: 0.4227 - val_loss: 0.9444 - 9s/epoch - 3s/step\n",
      "Epoch 2/50\n",
      "3/3 - 0s - loss: 0.4064 - val_loss: 0.9226 - 149ms/epoch - 50ms/step\n",
      "Epoch 3/50\n",
      "3/3 - 0s - loss: 0.3883 - val_loss: 0.8958 - 156ms/epoch - 52ms/step\n",
      "Epoch 4/50\n",
      "3/3 - 0s - loss: 0.3664 - val_loss: 0.8615 - 142ms/epoch - 47ms/step\n",
      "Epoch 5/50\n",
      "3/3 - 0s - loss: 0.3399 - val_loss: 0.8166 - 155ms/epoch - 52ms/step\n",
      "Epoch 6/50\n",
      "3/3 - 0s - loss: 0.3060 - val_loss: 0.7565 - 131ms/epoch - 44ms/step\n",
      "Epoch 7/50\n",
      "3/3 - 0s - loss: 0.2636 - val_loss: 0.6754 - 160ms/epoch - 53ms/step\n",
      "Epoch 8/50\n",
      "3/3 - 1s - loss: 0.2085 - val_loss: 0.5651 - 537ms/epoch - 179ms/step\n",
      "Epoch 9/50\n",
      "3/3 - 0s - loss: 0.1354 - val_loss: 0.4145 - 161ms/epoch - 54ms/step\n",
      "Epoch 10/50\n",
      "3/3 - 0s - loss: 0.0745 - val_loss: 0.2375 - 149ms/epoch - 50ms/step\n",
      "Epoch 11/50\n",
      "3/3 - 0s - loss: 0.1044 - val_loss: 0.0818 - 157ms/epoch - 52ms/step\n",
      "Epoch 12/50\n",
      "3/3 - 0s - loss: 0.1622 - val_loss: 0.0268 - 163ms/epoch - 54ms/step\n",
      "Epoch 13/50\n",
      "3/3 - 0s - loss: 0.2126 - val_loss: 0.0437 - 93ms/epoch - 31ms/step\n",
      "Epoch 14/50\n",
      "3/3 - 0s - loss: 0.2053 - val_loss: 0.0315 - 76ms/epoch - 25ms/step\n",
      "Epoch 15/50\n",
      "3/3 - 0s - loss: 0.1630 - val_loss: 0.0807 - 85ms/epoch - 28ms/step\n",
      "Epoch 16/50\n",
      "3/3 - 0s - loss: 0.1346 - val_loss: 0.1140 - 87ms/epoch - 29ms/step\n",
      "Epoch 17/50\n",
      "3/3 - 0s - loss: 0.1140 - val_loss: 0.1309 - 80ms/epoch - 27ms/step\n",
      "Epoch 18/50\n",
      "3/3 - 0s - loss: 0.1070 - val_loss: 0.1321 - 98ms/epoch - 33ms/step\n",
      "Epoch 19/50\n",
      "3/3 - 0s - loss: 0.0996 - val_loss: 0.1218 - 78ms/epoch - 26ms/step\n",
      "Epoch 20/50\n",
      "3/3 - 0s - loss: 0.1006 - val_loss: 0.1030 - 76ms/epoch - 25ms/step\n",
      "Epoch 21/50\n",
      "3/3 - 0s - loss: 0.1030 - val_loss: 0.0797 - 87ms/epoch - 29ms/step\n",
      "Epoch 22/50\n",
      "3/3 - 0s - loss: 0.1071 - val_loss: 0.0549 - 76ms/epoch - 25ms/step\n",
      "Epoch 23/50\n",
      "3/3 - 0s - loss: 0.1106 - val_loss: 0.0298 - 80ms/epoch - 27ms/step\n",
      "Epoch 24/50\n",
      "3/3 - 0s - loss: 0.1139 - val_loss: 0.0392 - 74ms/epoch - 25ms/step\n",
      "Epoch 25/50\n",
      "3/3 - 0s - loss: 0.0976 - val_loss: 0.0976 - 74ms/epoch - 25ms/step\n",
      "Epoch 26/50\n",
      "3/3 - 0s - loss: 0.0774 - val_loss: 0.1281 - 75ms/epoch - 25ms/step\n",
      "Epoch 27/50\n",
      "3/3 - 0s - loss: 0.0654 - val_loss: 0.1337 - 71ms/epoch - 24ms/step\n",
      "Epoch 28/50\n",
      "3/3 - 0s - loss: 0.0650 - val_loss: 0.1198 - 76ms/epoch - 25ms/step\n",
      "Epoch 29/50\n",
      "3/3 - 0s - loss: 0.0656 - val_loss: 0.0869 - 81ms/epoch - 27ms/step\n",
      "Epoch 30/50\n",
      "3/3 - 0s - loss: 0.0768 - val_loss: 0.0409 - 83ms/epoch - 28ms/step\n",
      "Epoch 31/50\n",
      "3/3 - 0s - loss: 0.0835 - val_loss: 0.0127 - 143ms/epoch - 48ms/step\n",
      "Epoch 32/50\n",
      "3/3 - 0s - loss: 0.1020 - val_loss: 0.0514 - 69ms/epoch - 23ms/step\n",
      "Epoch 33/50\n",
      "3/3 - 0s - loss: 0.1075 - val_loss: 0.0477 - 82ms/epoch - 27ms/step\n",
      "Epoch 34/50\n",
      "3/3 - 0s - loss: 0.1036 - val_loss: 0.0390 - 223ms/epoch - 74ms/step\n",
      "Epoch 35/50\n",
      "3/3 - 0s - loss: 0.0667 - val_loss: 0.1299 - 116ms/epoch - 39ms/step\n",
      "Epoch 36/50\n",
      "3/3 - 0s - loss: 0.0563 - val_loss: 0.1643 - 164ms/epoch - 55ms/step\n",
      "Epoch 37/50\n",
      "3/3 - 0s - loss: 0.0612 - val_loss: 0.1525 - 102ms/epoch - 34ms/step\n",
      "Epoch 38/50\n",
      "3/3 - 0s - loss: 0.0582 - val_loss: 0.1029 - 164ms/epoch - 55ms/step\n",
      "Epoch 39/50\n",
      "3/3 - 0s - loss: 0.0582 - val_loss: 0.0316 - 192ms/epoch - 64ms/step\n",
      "Epoch 40/50\n",
      "3/3 - 0s - loss: 0.0781 - val_loss: 0.0177 - 102ms/epoch - 34ms/step\n",
      "Epoch 41/50\n",
      "3/3 - 0s - loss: 0.0842 - val_loss: 0.0125 - 207ms/epoch - 69ms/step\n",
      "Epoch 42/50\n",
      "3/3 - 0s - loss: 0.0767 - val_loss: 0.0316 - 86ms/epoch - 29ms/step\n",
      "Epoch 43/50\n",
      "3/3 - 0s - loss: 0.0677 - val_loss: 0.0867 - 70ms/epoch - 23ms/step\n",
      "Epoch 44/50\n",
      "3/3 - 0s - loss: 0.0538 - val_loss: 0.0969 - 79ms/epoch - 26ms/step\n",
      "Epoch 45/50\n",
      "3/3 - 0s - loss: 0.0617 - val_loss: 0.0733 - 75ms/epoch - 25ms/step\n",
      "Epoch 46/50\n",
      "3/3 - 0s - loss: 0.0642 - val_loss: 0.0292 - 72ms/epoch - 24ms/step\n",
      "Epoch 47/50\n",
      "3/3 - 0s - loss: 0.0819 - val_loss: 0.0291 - 70ms/epoch - 23ms/step\n",
      "Epoch 48/50\n",
      "3/3 - 0s - loss: 0.0964 - val_loss: 0.0447 - 73ms/epoch - 24ms/step\n",
      "Epoch 49/50\n",
      "3/3 - 0s - loss: 0.0854 - val_loss: 0.0246 - 76ms/epoch - 25ms/step\n",
      "Epoch 50/50\n",
      "3/3 - 0s - loss: 0.0648 - val_loss: 0.1009 - 74ms/epoch - 25ms/step\n"
     ]
    },
    {
     "data": {
      "image/png": "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3LhRe/LJJz0dUpOy2+3arFmztIkTJ2qbN2/WNE3T7rzzTm316tWay+XSbr/9di0rK8vDUbrfwoULteXLl2uapmmrVq3S/ud//scryr1nzx7thx9+0DRN0w4dOqTdeeedXlHuny1fvlzr06eP9sUXX2h/+9vftIULF2qapmkPPfSQtmPHDg9H537Z2dnan/70p/O+19hye00z0W/3Zk5NTfV0SE3u+eefp1evXgA4nU4OHjzIqFGjUBSFYcOGsXXrVg9H6H7Tpk3jmmuuASA/P5+IiAivKHfv3r258sorOXr0KP/85z+59tprvaLcALm5uXzwwQfccsstQNXf+rXXXgvA6NGj2bhxoyfDaxLbtm3jwIEDTJs2jZtvvpm9e/c2utxe00xU172Z2wq9Xk9UVFT11xaLhXbt2lV/HRgYyNmzZz0RWrMoKCjg3//+N++99x579uyp/n5bL/eWLVvIyMjA19fXa37fTz31FI899hibNm0CqpbG9/ev2uu3rZY7ISGBf//738THx7Nt2zZefvnlRpfba5JBXfdmbqt8fHyw2WzVX7flPaftdjsPPvggDz74IFFRUV5TboBbb72VoUOHct9992G326u/31bLvWjRIhISEhgwYEB1MtDr9WiahqIolJeXezjCptGlSxfMZjMAPXr04OjRowQFBTWq3F7TTFTXvZnbKp1OR1BQENnZ2QDs37+fDh06eDgq93M6nTz44IOMHTuWsWPHek25Fy1axKuvvgpAUVERISEhXlHuH3/8ke3btzN9+nS+/PJL5s+fT35+Pjt37gTgwIEDbbLczz77LBs2bABg5cqV9OrVi6SkpEaV22s2t3E6nUybNo1evXqxY8cObrjhhjY/ugLg0Ucf5brrrmPQoEH8+OOPvPPOO/Tr149169axZMkS/Pz8PB2iW33++efMmTOHnj17AtC+fXsmTJjQ5stts9l4+OGHycnJwWQy8dRTT3H8+PE2X+5fe+utt4iJiSEhIYHHH3+ckSNHsnz5cj777LPzmkzbgqysLB544AEqKipo164dzz77LPn5+Y0qt9ckA6j6g0lJSSEiIuKiezO3ZUePHmX//v2MGjWKoKAgT4fTbKTc3lXurKwstm/fzuDBg8/rO2nrGlNur0oGQgghauY1fQZCCCFqJ8lACCGEJAMhmtOSJUtYsmSJp8MQ4gKSDIQQQnjPpDMhGspisfDII4+Qn59P165dCQ0NZffu3VRWVhIaGsrrr7+OXq/n+eef5+DBgwQGBvLSSy8RGBjIc889x8GDBzEYDLz++usAHDp0iBkzZpCXl8ebb75J165dPVxCIaRmIMQlffbZZyQmJvLxxx+Tm5vL4cOHGTBgAAsXLiQsLIxVq1bx008/YbVa+eSTTxg3bhzvvfceKSkpOJ1OPv30U+688072798PwN69e/nggw+YPXs2KSkpHi6dEFWkZiDEJRw/fpxdu3axdetWSkpKMBqN3HTTTQB069aNrKwsnE4nffv2BaBPnz58//33BAUF0bt3bwCuuOIKXC4XX331FZMmTcJgMBAWFsbRo0c9Vi4hfk1qBkJcQpcuXbj99tv56KOPuO+++4iOjq5e/O7AgQPExsaSmJhYvRLu7t27SUxMJC4ujr179wKwdOlS5s2bB1StEyVESyM1AyEu4fe//z2PPfYYS5Yswd/fn86dO7N3716mT59OeHg4Y8aMQVVV1q1bx6233npen8HatWuZNm0aZrOZV155hdWrV3u6OELUSGYgC1FPb731FgMHDmTQoEGeDkUIt5FkIIQQQvoMhBBCSDIQQgiBJAMhhBBIMhBCCIEkAyGEEEgyEEIIAfx/jNfWKr5ynUoAAAAASUVORK5CYII=\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# 搭建LSTM模型\n",
    "model = Sequential()\n",
    "\n",
    "model.add(LSTM(100, input_shape=(train_X.shape[1], train_X.shape[2]),return_sequences=True))\n",
    "\n",
    "model.add(Dropout(0.2))\n",
    "\n",
    "model.add(LSTM(100,return_sequences=True))\n",
    "model.add(LSTM(100,return_sequences=False))\n",
    "\n",
    "model.add(Dropout(0.2))\n",
    "\n",
    "model.add(Dense(1,activation='relu'))\n",
    "\n",
    "model.compile(loss='mae', optimizer='adam')\n",
    "\n",
    "if os.path.exists(checkpoint_save_path + '.index'):\n",
    "    print('-------------load the model-----------------')\n",
    "    model.load_weights(checkpoint_save_path)\n",
    "    \n",
    "# fit network\n",
    "history = model.fit(train_X, train_y, epochs=50, batch_size=100, validation_data=(test_X, test_y), verbose=2,shuffle=False,\n",
    "                    validation_freq=1,callbacks=[cp_callback])\n",
    " \n",
    "# 绘制损失图\n",
    "plt.plot(history.history['loss'], label='train')\n",
    "plt.plot(history.history['val_loss'], label='test')\n",
    "plt.title('LSTM损失图', fontsize='12')\n",
    "plt.ylabel('loss', fontsize='10')\n",
    "plt.xlabel('epoch', fontsize='10')\n",
    "plt.legend()\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "134ba838",
   "metadata": {},
   "source": [
    "* 预测并反转数据（反归一化）\n",
    "    * 需要将预测结果和测试集数据组合然后进行比例反转（invert the scaling），同时需要将测试集上的预期值也进行比例转换。 \n",
    "         这里为什么进行比例反转（反归一化）呢？（因为我们将原始数据进行了预处理（连同输出值y），此时的误差损失计算是在处理之后的数据上进行的，为了计算在原始比例上的误差需要将数据进行转化。反转时的矩阵大小一定要和原来的大小（shape）完全相同，否则就会报错。）"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "id": "b024ee64",
   "metadata": {
    "scrolled": true
   },
   "outputs": [],
   "source": [
    "#模型预测收益率\n",
    "y_predict = model.predict(test_X)\n",
    "test_X = test_X.reshape((test_X.shape[0], test_X.shape[2]))\n",
    " \n",
    "# invert scaling for forecast\n",
    "#将预测结果按比例反归一化\n",
    "inv_y_test = np.concatenate((test_X[:, :6],y_predict), axis=1)\n",
    "inv_y_test = scaler.inverse_transform(inv_y_test)\n",
    "inv_y_predict=inv_y_test[:,-1]\n",
    " \n",
    "# invert scaling for actual\n",
    "#将真实结果按比例反归一化\n",
    "test_y = test_y.reshape((len(test_y), 1))\n",
    "inv_y_train = np.concatenate((test_X[:, :6],test_y), axis=1)\n",
    "inv_y_train = scaler.inverse_transform(inv_y_train)\n",
    "inv_y = inv_y_train[:, -1]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "id": "9220b6f0",
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>反归一化后的预测结果</th>\n",
       "      <th>反归一化后的真实结果</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>8.615442</td>\n",
       "      <td>8.622</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>8.615470</td>\n",
       "      <td>8.622</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>8.615196</td>\n",
       "      <td>8.622</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>8.615523</td>\n",
       "      <td>8.622</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>8.615425</td>\n",
       "      <td>8.622</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "   反归一化后的预测结果  反归一化后的真实结果\n",
       "0    8.615442       8.622\n",
       "1    8.615470       8.622\n",
       "2    8.615196       8.622\n",
       "3    8.615523       8.622\n",
       "4    8.615425       8.622"
      ]
     },
     "execution_count": 22,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "data = pd.DataFrame({\"反归一化后的预测结果\":inv_y_predict,'反归一化后的真实结果':inv_y})\n",
    "data.head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "id": "4afb1ae4",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.plot(inv_y,color='red',label='Original')\n",
    "plt.plot(inv_y_predict,color='green',label='Predict')\n",
    "plt.xlabel('the number of test data')\n",
    "plt.ylabel('close')\n",
    "plt.title('预测与实际数据图')\n",
    "plt.legend()\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "id": "7b6485c6",
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "均方误差: 0.000045\n",
      "均方根误差: 0.006684\n",
      "平均绝对误差: 0.006559\n"
     ]
    }
   ],
   "source": [
    "from sklearn.metrics import mean_squared_error, mean_absolute_error\n",
    "# 评估\n",
    "# calculate MSE 均方误差 ---> E[(预测值-真实值)^2] (预测值减真实值求平方后求均值)\n",
    "mse = mean_squared_error(inv_y_predict, inv_y)\n",
    "# calculate RMSE 均方根误差--->sqrt[MSE]    (对均方误差开方)\n",
    "rmse = math.sqrt(mean_squared_error(inv_y_predict, inv_y))\n",
    "# calculate MAE 平均绝对误差----->E[|预测值-真实值|](预测值减真实值求绝对值后求均值）\n",
    "mae = mean_absolute_error(inv_y_predict, inv_y)\n",
    "print('均方误差: %.6f' % mse)\n",
    "print('均方根误差: %.6f' % rmse)\n",
    "print('平均绝对误差: %.6f' % mae)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "id": "2416ac22",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "准确率：0.9992715082431637\n"
     ]
    }
   ],
   "source": [
    "#ACC\n",
    "error = 0\n",
    "summery = 0\n",
    "for i in range(24):\n",
    "    error += abs(inv_y_predict[i] - inv_y[i])\n",
    "    summery += inv_y[i]\n",
    "acc = 1 - error/summery\n",
    "print(\"准确率：{}\".format(acc))"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "deep",
   "language": "python",
   "name": "deep"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.9.7"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
